package com.hang.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hang.common.BizErrorCodeEnum;
import com.hang.common.BizException;
import com.hang.common.ResultCodeEnum;

import org.joda.time.DateTime;

import com.hang.config.RedisConfig;
import com.hang.mapper.*;
import com.hang.model.*;
import com.hang.service.LeaveService;
import com.hang.util.ConstantOssPropertiesUtils;
import com.hang.vo.LeaveVo;
import com.hang.vo.LeavesDTO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.*;

/**
 *
 */
@Service
public class LeaveServiceImpl extends ServiceImpl<LeaveMapper, Leave>
    implements LeaveService{

    @Autowired
    private ClazzMapper clazzMapper;

    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private TeacherMapper teacherMapper;

    @Autowired
    private LeaveMapper leaveMapper;

    @Autowired
    private AttendanceMapper attendanceMapper;

    @Autowired
    private RedisConfig redisConfig;
    /**
     * 获取老师所有的请假条信息
     * @param teacherId
     * @param page
     * @param size
     * @return
     */
    @Override
    public List<LeavesDTO> getAllLeaves(String teacherId, Integer page, Integer size) {
        if(StringUtils.isBlank(teacherId)){
            throw new BizException(BizErrorCodeEnum.ID_IS_NULL);
        }

        //分页查询所有请假申请
        QueryWrapper<Leave> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("teacher_id",teacherId);

        Page<Leave> pages = new Page<>(page,size);
        IPage<Leave> iPage = leaveMapper.selectPage(pages,queryWrapper);
        
        //得到相对应的页数和条数内容,仅展示这部分数据，懒加载
        List<Leave> leaves = iPage.getRecords();

        if(leaves.size() == 0){
            return new ArrayList<>();       //暂时没有请假申请
        }

        List<LeavesDTO> result = new LinkedList<>();

        for (Leave leave : leaves){
            LeavesDTO dto = new LeavesDTO();
            Long taskId = leave.getTaskId();
            String studentId = leave.getStudentId();
            String clazzId = leave.getClazzId();


            dto.setId(leave.getId());
            dto.setTitle(leave.getTitle());
            dto.setContent(leave.getContent());
            dto.setTaskId(taskId);
            dto.setStudentId(studentId);
            dto.setClazzId(clazzId);
            dto.setStatus(leave.getStatus());

            dto.setLatitude(leave.getLatitude());
            dto.setLongitude(leave.getLongitude());
            dto.setLocation(leave.getLocation());
            dto.setLocationName(leave.getLocationName());

            /**
             * 关联查找其它的信息
             * 1.班级信息
             * 2.任务信息
             * 3.学生信息
             */

            QueryWrapper<Clazz> clazzQueryWrapper = new QueryWrapper<>();
            clazzQueryWrapper.eq("clazz_id",clazzId);
            String clazzName = clazzMapper.selectOne(clazzQueryWrapper).getClazzName();
            if(!StringUtils.isBlank(clazzName)){
                dto.setClazzName(clazzName);
            }

            Task task = taskMapper.selectById(taskId);

            if(!ObjectUtils.isEmpty(task)){
                String taskName = task.getName();
                LocalDateTime startTime = task.getStartTime();
                LocalDateTime endTime = task.getEndTime();

                dto.setTaskName(taskName);
                dto.setStartTime(startTime);
                dto.setEndTime(endTime);
            }

            QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
            studentQueryWrapper.eq("student_id",studentId);

            String studentName = studentMapper.selectOne(studentQueryWrapper).getRealName();
            if(!StringUtils.isBlank(studentName)){
                dto.setStudentName(studentName);
            }

            //打包完成
            result.add(dto);
        }

        return result;
    }

    @Override
    public boolean hasMoreData(String teacherId, Integer page, Integer size) {
        QueryWrapper<Leave> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("teacher_id",teacherId);

        int totals = leaveMapper.selectCount(queryWrapper);

        return totals>page*size ? Boolean.TRUE:Boolean.FALSE;
    }

    /**
     * 查看请假的具体细节
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> detail(Long id) {

        Map<String,Object> map = new HashMap<>();

        //找到对应的请假信息
        Leave leave = leaveMapper.selectById(id);
        Long taskId = leave.getTaskId();

        if(ObjectUtils.isEmpty(leave)){
            throw new BizException(BizErrorCodeEnum.GET_LEAVE_FAIL);
        }

        map.put("title",leave.getTitle());
        map.put("studentId",leave.getStudentId());
        map.put("clazzId",leave.getClazzId());
        map.put("content",leave.getContent());
        map.put("pictureUrl",leave.getPictureUrl());
        map.put("status",leave.getStatus());

        map.put("latitude",leave.getLatitude());
        map.put("longitude",leave.getLongitude());
        map.put("location",leave.getLocation());
        map.put("locationName",leave.getLocationName());

        QueryWrapper<Student> studentQueryWrapper = new QueryWrapper<>();
        studentQueryWrapper.eq("student_id",leave.getStudentId());

        String studentName  = studentMapper.selectOne(studentQueryWrapper).getRealName();
        if(StringUtils.isNotBlank(studentName)){
            map.put("studentName",studentName);
        }

        QueryWrapper<Clazz> clazzQueryWrapper = new QueryWrapper<>();
        clazzQueryWrapper.eq("clazz_id",leave.getClazzId());

        String clazzName = clazzMapper.selectOne(clazzQueryWrapper).getClazzName();
        if(StringUtils.isNotBlank(clazzName)){
            map.put("clazzName",clazzName);
        }


        Task task = taskMapper.selectById(taskId);

        if(!ObjectUtils.isEmpty(task)){
            String taskName = task.getName();
            LocalDateTime startTime = task.getStartTime();
            LocalDateTime endTime = task.getEndTime();

            map.put("taskName",taskName);
            map.put("startTime",startTime);
            map.put("endTime",endTime);
        }

        //打包完成，带走即可
        return map;
    }

    /**
     * 请假审批:事务
     *
     * @param id
     * @param status
     * @return
     */
    @Override
    @Transactional
    public Integer approval(Long id, Integer status) {
        Leave leave = leaveMapper.selectById(id);
        leave.setStatus(status);

        //更新假条的审批状态
        leaveMapper.updateById(leave);
        //去对应的任务下更改这个学生的状态:先redis后mysql

        //审批通过才去更改状态
        if(status == 1){
            Long taskId = leave.getTaskId();
            String studentId = leave.getStudentId();
            RedisTemplate<String, Object> redisTemplate = redisConfig.getRedisTemplateByDb(1);

            redisTemplate.opsForHash().put(String.valueOf(taskId),studentId,2);

            //将redis中的数据同步回mysql中
            QueryWrapper<Attendance> attendanceQueryWrapper = new QueryWrapper<>();
            attendanceQueryWrapper.eq("task_id",taskId);
            attendanceQueryWrapper.eq("student_id",studentId);

            Attendance attendance = attendanceMapper.selectOne(attendanceQueryWrapper);
            attendance.setStatus(2);

            attendanceMapper.updateById(attendance);
        }

        return Integer.valueOf("200");
    }

    @Override
    public Map<String, Object> apply(LeaveVo leaveVo,String url) {
        if(ObjectUtils.isEmpty(leaveVo)){
            throw new BizException(BizErrorCodeEnum.OBJECT_IS_NULL);
        }

        //先存入基本数据
        Leave leave = new Leave();
        BeanUtils.copyProperties(leaveVo,leave);

        //再存入拓展数据
        final Long taskId = leaveVo.getTaskId();
        final Task task = taskMapper.selectById(taskId);
        leave.setClazzId(task.getClazzId());
        leave.setTeacherId(task.getTeacherId());

        if(StringUtils.isNotBlank(url)){
            //存入图片地址
            leave.setPictureUrl(url);
        }

        Map<String,Object> map = new HashMap<>();

        map.put("insert","fail");
        leaveMapper.insert(leave);

        //更新插入状态
        map.put("insert","success");
        return map;
    }

    /**
     * 获取学生的请假数目
     * @param studentId
     * @return
     */
    @Override
    public Integer getStudentCounts(String studentId) {
        QueryWrapper<Leave> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("student_id",studentId);

        final Integer num = leaveMapper.selectCount(queryWrapper);

        return num > 0? num:0;
    }

    /**
     * 统计功能：获取教师管理的请假数目
     * @param teacherId
     * @return
     */
    @Override
    public Integer getTeacherCounts(String teacherId) {
        QueryWrapper<Leave> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("teacher_id",teacherId);

        final Integer count = leaveMapper.selectCount(queryWrapper);

        return count>0?count:0;
    }

    @Override
    public boolean hasMoreStudentData(String studentId, Integer page, Integer size) {
        QueryWrapper<Leave> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("student_id",studentId);

        int totals = leaveMapper.selectCount(queryWrapper);

        return totals>page*size ? Boolean.TRUE:Boolean.FALSE;
    }

    /**
     * 获取学生的请假记录：按照请假提交时间
     *
     * @param studentId
     * @param page
     * @param size
     * @return
     */
    @Override
    public List<LeavesDTO> getMyLeaves(String studentId, Integer page, Integer size) {
        if(StringUtils.isBlank(studentId)){
            throw new BizException(BizErrorCodeEnum.ID_IS_NULL);
        }

        //分页查询所有请假申请
        QueryWrapper<Leave> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("student_id",studentId);
        queryWrapper.orderByDesc("create_time");

        Page<Leave> pages = new Page<>(page,size);
        IPage<Leave> iPage = leaveMapper.selectPage(pages,queryWrapper);

        //得到相对应的页数和条数内容,仅展示这部分数据，懒加载
        List<Leave> leaves = iPage.getRecords();

        if(leaves.size() == 0){
            return new ArrayList<>();       //暂时没有请假申请
        }

        List<LeavesDTO> result = new LinkedList<>();

        for (Leave leave : leaves){
            LeavesDTO dto = new LeavesDTO();
            Long taskId = leave.getTaskId();
            String clazzId = leave.getClazzId();

            BeanUtils.copyProperties(leave,dto);

            /**
             * 关联查找其它的信息
             * 1.班级信息
             * 2.任务信息
             */

            QueryWrapper<Clazz> clazzQueryWrapper = new QueryWrapper<>();
            clazzQueryWrapper.eq("clazz_id",clazzId);
            String clazzName = clazzMapper.selectOne(clazzQueryWrapper).getClazzName();
            if(!StringUtils.isBlank(clazzName)){
                dto.setClazzName(clazzName);
            }

            Task task = taskMapper.selectById(taskId);

            if(!ObjectUtils.isEmpty(task)){
                String taskName = task.getName();
                LocalDateTime startTime = task.getStartTime();
                LocalDateTime endTime = task.getEndTime();

                dto.setTaskName(taskName);
                dto.setStartTime(startTime);
                dto.setEndTime(endTime);
            }

            //打包完成
            result.add(dto);
        }
        return result;
    }
}